package com.weibo.game;

import java.net.URL;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


/**
 *  异步通知示例 ，主要做如何校验 【signature】
 */
public class PayAsyncNotify {
    
    /** 分配给游戏方的appSecret */
    public static final String appSecret = "60ba6db971f6072e38155933250270a3";
    
    /** 异步通知示例,接口地址由游戏方提供，参数值校验  */
    public static final String notifyURL = "http://m2.game.weibo.cn/pay/callback?order_id=sng55Cy7aa1AYhL&amount=103&order_uid=200000000007&source=3470157549&actual_amount=103&signature=f55091c42c6d29352bc03026ea7d6a20a6b8920d";
    
    public static void main(String[] args) {
        
        boolean validate = false;
        try {
            System.out.println("********************************");
            Map<String,String> params = getParams(notifyURL);
            System.out.println("********************************");
            
            System.out.println("开始校验签名串");
            validate = validateSignature(params,appSecret);
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        if(validate){
            System.out.println("signature 验证通过");
        }else{
            System.out.println("signature 验证不通过");
        }
        
    }

    private static Map<String,String> getParams(String url) throws Exception {
        URL u = new URL(url);
        String query = u.getQuery();
        System.out.println("获取参数串:"+query);
        String[] params = query.split("&");
        Map<String, String> container = new HashMap<String,String>();
        String key = null;
        String value = null;
        for(String param : params){
            int index = param.indexOf("=");
            if(index != -1){
                key = param.substring(0, index);
                value = URLDecoder.decode(param.substring(index+1),"UTF-8");
            }else{
                key = param;
                value = "";
            }
            System.out.println("key:"+key+",value:"+value);
            container.put(key, value);
        }
        return container;
    }

    /***************** 以下代码可复制，用于计算signature *****************/
    private static boolean validateSignature(Map<String, String> params,String appSecret) {
        if(params != null){
            StringBuilder sValue = new StringBuilder();
            Object[] keys = params.keySet().toArray();
            Arrays.sort(keys);
            String temp = null;
            for(Object key : keys){
                if(!key.equals("signature")){
                    sValue.append(key).append("|");
                    temp = params.get(key);
                    if(temp == null){
                        sValue.append("").append("|");
                    }else{
                        sValue.append(temp).append("|");
                    }
                }
            }
                sValue.append(appSecret);
            String localSignature =getSHA1(sValue.toString());
            System.out.println("运算的签名串："+localSignature);
            
            if(localSignature.equals(params.get("signature"))){
                return true;
            }else{
                return false;
            }
            
        }
        return false;
        
    }
    
    /**
     * 对字符串进行sha1编码
     * @param input
     * @return
     */
    public static String getSHA1(String input) {
        return encrypt(input, "SHA-1");
    }
    
    public static String encrypt(String strSrc, String encName) {
        MessageDigest md = null;
        String strDes = null;
        byte[] bt = strSrc.getBytes();
        try {
            if (encName == null || encName.equals("")) {
                encName = "MD5";
            }
            md = MessageDigest.getInstance(encName);
            md.update(bt);
            strDes = bytes2Hex(md.digest()); // to HexString
        }
        catch (NoSuchAlgorithmException e) {
            System.out.println("Invalid algorithm.");
            return null;
        }

        return strDes;
    }
    

    public static String bytes2Hex(byte[] bts) {
        String des = "";
        String tmp = null;
        for (int i = 0; i < bts.length; i++) {
            tmp = (Integer.toHexString(bts[i] & 0xFF));
            if (tmp.length() == 1) {
                des += "0";
            }
            des += tmp;
        }
        return des;
    }
    
    
}
